package com.huantai.common.util.auth;

import com.huantai.common.consts.BizConst;
import com.huantai.common.enums.ExpiresTypeEnum;
import com.huantai.common.exception.BusinessException;
import com.huantai.common.exception.SystemException;
import com.huantai.common.util.secret.AESUtil;
import com.huantai.common.util.ConvertUtil;
import com.huantai.common.util.StringUtil;

/**
 * AccessToken工具类
 * 
 * @author Ma Chao
 * @version 2019年5月22日 下午2:38:10
 */
public final class AccessTokenUtil {
    private AccessTokenUtil() {}

    // @formatter:off
    /**
     * 生成AccessToken
     * 
     * @param type 失效类型
     * @param value 失效类型不是NERVER时，失效时间对应的值
     * @param id 可选的取值范围：<br/>
     *            1) 系统用户Id <br/>
     *            2) 客户Id <br/>
     *            3) 系统Id 
     * @param reqFrom 请求来源: <br/>
     *            1) 当id取值为系统用户Id时，取<code>AuthorityConstDef.FROM_USER</code> <br/>
     *            2) 当id取值为客户Id时，取<code>AuthorityConstDef.FROM_APP</code> <br/>
     *            3) 当id取值为系统Id时，取<code>AuthorityConstDef.FROM_SYSTEM</code> 
     * @param sysNodeId 系统节点Id <br/>
     *            1) 当reqFrom取值为<code>AuthorityConstDef.FROM_SYSTEM</code>时，为系统节点Id <br/>
     *            2) 否则取<code>AuthorityConstDef.DEFAULT_NODE_ID</code>
     */
    // @formatter:on
    public static String generateToken(ExpiresTypeEnum type, int value, String id, String reqFrom,
                                       String sysNodeId) {
        String token = null;
        String expiresTime = getExpiresTime(type, value);
        try {
            token = AESUtil.encode(StringUtil.formatMessage(BizConst.AuthorityConstDef.TOKEN_PARTEN, id,
                    reqFrom, sysNodeId, expiresTime));
        } catch (Exception e) {
            throw new SystemException(
                    StringUtil.formatMessage("生成AccessToken出错！ {0}", e.getMessage()));
        }
        return token;
    }

    /**
     * 根据过期类型和对应的值生成过期时间
     */
    private static String getExpiresTime(ExpiresTypeEnum type, int value) {
        long time = System.currentTimeMillis();
        long timeAdd = 0l;
        if (ExpiresTypeEnum.NERVER == type) {
            return ConvertUtil.toString(Long.MAX_VALUE);
        }

        if (ExpiresTypeEnum.DAYS == type) {
            timeAdd = value * 24 * 60 * 60 * 1000l;
        }
        if (ExpiresTypeEnum.HOURS == type) {
            timeAdd = value * 60 * 60 * 1000l;
        }
        if (ExpiresTypeEnum.MINUTES == type) {
            timeAdd = value * 60 * 1000l;
        }
        return ConvertUtil.toString(time + timeAdd);
    }

    /**
     * 根据用户访问令牌获取用户ID
     */
    public static String getUserIdByUserAccessToken(String userAccessToken) {
        String userId = null;
        try {
            // 解析UserToken
            String decodedToken = AESUtil.decode(userAccessToken);
            userId = decodedToken.split(",")[0];
            if (StringUtil.isEmpty(userId)) {
                throw new BusinessException("从AccessToken获取用户ID失败！");
            }
        } catch (Exception e) {
            throw new BusinessException(
                    StringUtil.formatMessage("AccessToken解析出错：{0}", e.getMessage()));
        }

        return userId;
    }
}
